#ifndef _SYSCORE_H
#define _SYSCORE_H

#include <pthread.h>  
#include <semaphore.h> 
#include <stdio.h>
#include <stdint.h>
#include <memory.h>
#include <syslog.h>
#include <libgen.h>

#include "msgcmn.h"

#ifdef __cplusplus
extern "C"{
#endif

typedef int8_t S8;
typedef uint8_t U8;
typedef volatile uint8_t V8;

typedef int16_t S16;
typedef uint16_t U16;
typedef volatile uint16_t V16;

typedef int32_t S32;
typedef uint32_t U32;
typedef volatile uint32_t V32;

typedef int64_t S64;
typedef uint64_t U64;
typedef volatile uint64_t V64;
typedef U8 BOOL;
#define TRUE 1
#define FALSE 0

typedef void* PTR;

#define ignore(x)

#define	DEBUG_ALWAYS    7
#define	DEBUG_INFO      6
#define	DEBUG_NOTICE    5 
#define	DEBUG_WARNING   4
#define	DEBUG_ERROR     3
#define	DEBUG_CRIT      2
#define	DEBUG_ALTERT    1
#define	DEBUG_EMERG     0
#define DEBUG_MAX_LEVEL 8

/****syslog level defintions
LOG_EMERG       0    system is unusable
LOG_ALERT      1    action must be taken immediately
LOG_CRIT       2    critical conditions
LOG_ERR        3    error conditions
LOG_WARNING    4    warning conditions
LOG_NOTICE     5    normal, but significant, condition
LOG_INFO       6    informational message
LOG_DEBUG      7    debug-level message
***/


#define LOG_MAX_LEVEL   DEBUG_ALWAYS

extern char* debugstr[];
extern U32 debuglevel;
#define dbgprintf(th,fd,fmt,args...) if(th<=debuglevel) \
                              {char sbuf[512];\
                              char filename[512];\
                              time_t timep=time(NULL);\
                              struct tm p={0} ;\
                              localtime_r(&timep,&p);\
                              strcpy(filename,__FILE__);\
                              sprintf(sbuf,"[%s] %04d/%02d/%02d %02d:%02d:%02d %s:%d %s",debugstr[th],(1900+p.tm_year),(1+p.tm_mon),p.tm_mday,p.tm_hour,p.tm_min,p.tm_sec,basename(filename),__LINE__,fmt);\
                              fprintf(fd,sbuf,args);}

#define dbgprintf_s(th,fd,fmt,args...) if(th<=debuglevel) \
                              {char sbuf[512];\
                              sprintf(sbuf,"%s",fmt);\
                              fprintf(fd,sbuf,args);}

#define RESULT		U32
#define RC_OK 		            0x0000
#define RC_FAIL		            0x0001
#define RC_OUT_OF_MEMORY        0x0002
#define RC_NULL_RESULT          0x0003
#define RC_MSG_TOO_LONG		    0x0004
#define RC_MSG_NO_BUFF	        0x0005
#define RC_MSG_DST_INVALID	    0x0006
#define RC_MSG_QUEUE_FULL       0x0007
#define RC_MSG_CORRUPTED        0x0008
#define RC_MSG_INVALID_VALUE     0x0009
#define RC_MOD_INVALID        0x00010


#define __align(x) __attribute__((aligned(x)))
#define IsAddressAligned(addr)  ((addr & (sizeof(PTR) -1)) == 0 )

#define SYS_lock_t      pthread_mutex_t
#define SYS_lock(x)     pthread_mutex_lock(x)
#define SYS_unlock(x)   pthread_mutex_unlock(x)
#define SYS_lock_init(x) pthread_mutex_init(x,NULL)
#define SYS_lock_destory(x) pthread_mutex_destroy(x)

#define SYS_sema_t       sem_t
#define SYS_sema_post(x) sem_post(x)
#define SYS_sema_wait(x) while((sem_wait(x)!= 0) &&(errno == EINTR)){continue;}
#define SYS_sema_init(x) sem_init(x,0,0)
#define SYS_sema_destory(x) sem_destroy(x)

#define K 1024
#define MSG_BUFF_SIZE (4*K)
#define MAX_MSG_SIZE (4*K - sizeof(MSGHEADER))




// const char *msgqueue_app[] = {"null", "detector", "interface", "sms", "cli", "fwmgr"};

typedef struct tagMODREG{
    U16 modID;
    BOOL needTick;
    BOOL needModTimer;
    U32 tickPeriod;  //unit ms. must be multiple of 100ms
    char *logIdent;
} MODREG, *PMODREG;


extern RESULT MOD_register(PMODREG pModReg);
extern RESULT MOD_deregister(U16 modID);

extern RESULT MSG_send(U16 peerID, MSGHEADER* pMsgHeader, void* pMsgPayload);
extern RESULT MSG_read(U16 selfID, MSGHEADER* pMsgHeader, void* pMsgPayload);
extern RESULT MSG_read_nonblock(U16 selfID, MSGHEADER* pMsgHeader, void* pMsgPayload);

extern void MOD_timerProc(U16 modID);
extern void* MOD_timerStart(U16 modID,U32 msTime, void (*cb)(void *), void *Param);
extern RESULT MOD_timerClear(U16 modID, void* pTimerInfo);
extern void MOD_timerRestart(void* pTimerInfo, U32 msTime);

extern RESULT SYS_init(void);
extern void MSG_printStats(void);
extern void MOD_log(U16 modID,int priority, const char* fmt, ... );
extern RESULT SYS_setLogLevel(U32 loglevel);
extern RESULT SYS_setDebugLevel(U32 level);



#ifdef __cplusplus
}
#endif

#endif
